package org.azj.dbOperatorComponent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public abstract class TransactionTemplate implements IJobManager
{
	protected ITransaction transactionManager;
    
	protected List<ICommand> jobList;
	
	protected List< List<HashMap<String, Object>> > resultSets;
    
	private ThreadLocal<String> localErrMsgHolder = new ThreadLocal<String>();
	
    protected TransactionTemplate(ITransaction transactionManager)
    {
    	this.transactionManager = transactionManager;
    	// originally no err message
    	localErrMsgHolder.set("");
    	jobList = new ArrayList<ICommand>();
    }
    
    @Override
    public List< List<HashMap<String, Object>> > doJobsInTransaction() throws SQLException
    {
        try
        {
            transactionManager.start();
            resultSets = new ArrayList<List<HashMap<String, Object>>>();
            resultSets.addAll(doAllJobs());
            transactionManager.commit();
        } 
        catch (SQLException e)
        {
        	transactionManager.rollback();
            resultSets.clear();
            // 如果事务失败，则返回null，并返回错误信息
            resultSets = null;
            
            String errMsg = e.getMessage();
            try {
            	// 运行db2程序来解释错误信息
            	Process process = Runtime.getRuntime().exec("db2.exe ? sql" + e.getErrorCode());
            	// 获取输出
            	errMsg += "\n" + readProcessOutput(process.getInputStream());
			} catch (IOException e2) {
				errMsg += "读取数据库错误输出时出现错误 : " + e2.getMessage();
			}
            finally {
            	localErrMsgHolder.set(errMsg);	
            }
        }
        catch (Exception exception) {
        	transactionManager.rollback();
            resultSets.clear();
            // 如果事务失败，则返回null，并返回错误信息
            resultSets = null;
            
            String errMsg = "未知错误 ： " + exception.getMessage();
            localErrMsgHolder.set(errMsg);
        }
        finally
        {
            transactionManager.close();
        }
        
        return resultSets;
    }

    @Override
    public String getLastError()
    {
    	return localErrMsgHolder.get();
    }
    
    protected abstract List< List<HashMap<String, Object>> > doAllJobs() throws SQLException;
    
	@Override
	public void addJob(ICommand command) {
		jobList.add(command);
	}
	
	@Override
	public void removeJob(ICommand command) 
	{
		if (jobList.contains(command))
		{
			jobList.remove(command);
		}
	}

	@Override
	public void removeJob(int index) 
	{
		if (index < 0 || jobList.size() > index)
		{
			return;
		}
		
		jobList.remove(index);
	}
	
	// private methods
    // 读取输入流
    private String readProcessOutput(InputStream inputStream) throws IOException{
    	String buf = "";
    	try {
            BufferedReader reader = new BufferedReader(
            		new InputStreamReader(inputStream, "gb2312"));
  
            String line;
            while ((line = reader.readLine()) != null) {
                buf += line + "\n";
            }
        }
        catch (IOException e) {
            throw e;
        }
        finally {
        	try {
                inputStream.close();
            } 
            catch (IOException e) {
                throw e;
            }
        }
    	
    	return buf;
    }

}
